package com.mzj.saas.commons.util;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class StringUtils extends org.apache.commons.lang3.StringUtils {

	/**
	 * 字符串转换成十六进制字符串
	 * 
	 * @param str
	 * @return
	 */
	public static String str2HexStr(String str) {
		char[] chars = "0123456789ABCDEF".toCharArray();
		StringBuilder sb = new StringBuilder("");
		byte[] bs = str.getBytes();
		int bit;
		for (int i = 0; i < bs.length; i++) {
			bit = (bs[i] & 0x0f0) >> 4;
			sb.append(chars[bit]);
			bit = bs[i] & 0x0f;
			sb.append(chars[bit]);
		}
		return sb.toString();
	}

	/**
	 * 把16进制字符串转换成字节数组
	 * 
	 * @param hexString
	 * @return byte[]
	 */
	public static byte[] hexStr2Byte(String hexStr) {
		byte[] baKeyword = new byte[hexStr.length() / 2];
		for (int i = 0; i < baKeyword.length; i++) {
			baKeyword[i] = (byte) (0xff & Integer.parseInt(hexStr.substring(i * 2, i * 2 + 2), 16));
		}
		return baKeyword;
	}

	/**
	 * 数组转成十六进制字符串
	 * 
	 * @param byte[]
	 * @return HexString
	 */
	public static String Byte2HexStr(byte[] b) {
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < b.length; ++i) {
			buffer.append(Byte2HexStr(b[i]));
		}
		return buffer.toString();
	}

	/**
	 * byte 转成十六进制字符串
	 * 
	 * @param b
	 * @return
	 */
	public static String Byte2HexStr(byte b) {
		String s = Integer.toHexString(b & 0xFF);
		if (s.length() == 1) {
			return "0" + s;
		} else {
			return s;
		}
	}

	/**
	 * 十六进制字符串转换字符串
	 * 
	 * @param HexString
	 * @return String
	 */
	public static String hexStr2Str(String hexStr) {
		String result = null;
		byte[] baKeyword = new byte[hexStr.length() / 2];
		for (int i = 0; i < baKeyword.length; i++) {
			baKeyword[i] = (byte) (0xff & Integer.parseInt(hexStr.substring(i * 2, i * 2 + 2), 16));

		}
		try {
			result = new String(baKeyword, "utf-8");// UTF-16le:Not
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return result;
	}

	private static final String BLANK = "";

	public static final String merge(Collection<?> list, String delim) {
		if (list == null || list.isEmpty())
			return BLANK;

		StringBuilder sb = new StringBuilder();

		Iterator<?> iter = list.iterator();
		while (iter.hasNext()) {
			Object obj = iter.next();

			if (obj != null)
				sb.append(obj.toString().trim());

			if (iter.hasNext())
				sb.append(delim);
		}

		return sb.toString();
	}

	public static final String merge(List<?> list, String delim) {
		if (list == null)
			return BLANK;

		int size = list.size();
		if (size == 0)
			return BLANK;

		Object obj = list.get(0);
		if (size == 1)
			return obj == null ? BLANK : obj.toString();

		StringBuilder sb = new StringBuilder();
		if (obj != null)
			sb.append(obj.toString().trim());

		for (int i = 1; i < size; i++) {
			sb.append(delim);
			obj = list.get(i);
			if (obj != null)
				sb.append(obj.toString().trim());
		}

		return sb.toString();
	}

	public static final String merge(Object array[], String delim) {
		if (array == null || array.length < 1)
			return BLANK;

		if (array.length == 1)
			return array[0] == null ? BLANK : array[0].toString();

		StringBuilder sb = new StringBuilder();
		if (array[0] != null)
			sb.append(array[0].toString().trim());

		for (int i = 1; i < array.length; i++) {
			sb.append(delim);

			Object obj = array[i];
			if (obj != null)
				sb.append(obj.toString().trim());
		}

		return sb.toString();
	}

	public static final boolean contains(String str, String substr, char delim) {
		if (str == null || str.isEmpty() || substr == null || substr.isEmpty())
			return false;

		int pos = 0;
		int sublen = substr.length();
		int len = str.length();

		while ((pos = str.indexOf(substr, pos)) >= 0) {
			pos += sublen;
			if (pos == len)
				return true;

			if (str.charAt(pos) == delim)
				return true;
			else
				pos++;
		}

		return false;
	}

	public static final boolean contains(String str, String substr, String delim) {
		if (str == null || str.isEmpty() || substr == null || substr.isEmpty())
			return false;

		int pos = 0;
		int sublen = substr.length();
		int len = str.length();
		int delimpos = 0;
		int delimlen = delim.length();

		while ((pos = str.indexOf(substr, pos)) >= 0) {
			pos += sublen;
			if (pos == len)
				return true;

			delimpos = str.indexOf(delim, pos);
			if (delimpos < 0)
				return false;
			else if (delimpos == pos)
				return true;

			pos = delimpos + delimlen;
		}

		return false;
	}

	public static final int count(String str, char ch) {
		if (str == null || str.isEmpty())
			return 0;

		int pos = 0;
		int count = 0;
		while ((pos = str.indexOf(ch, pos)) >= 0) {
			count++;
			pos++;
		}

		return count;
	}

	public static final int count(String str, String substr) {
		if (str == null || str.isEmpty() || substr == null || substr.isEmpty())
			return 0;

		int count = 0;
		int pos = str.indexOf(substr);
		int sublen = substr.length();
		while ((pos = str.indexOf(substr, pos)) >= 0) {
			count++;
			pos += sublen;
		}

		return count;
	}

	public static final boolean startsWith(String str, char begin) {
		if (str == null || str.isEmpty())
			return false;

		return str.charAt(0) == begin;
	}

	public static final boolean startsWithIgnoreCase(String str, char begin) {
		if (str == null || str.isEmpty())
			return false;

		return Character.toLowerCase(str.charAt(0)) == Character.toLowerCase(begin);
	}

	public static final boolean startsWithIgnoreCase(String str, String start) {
		if ((str == null) || (start == null))
			return false;

		if (start.length() > str.length())
			return false;

		String temp = str.substring(0, start.length());

		return temp.equalsIgnoreCase(start);
	}

	public static final boolean endsWith(String str, char end) {
		if (str == null || str.isEmpty())
			return false;

		return str.charAt(str.length() - 1) == end;
	}

	public static final boolean endsWithIgnoreCase(String str, char end) {
		if (str == null || str.isEmpty())
			return false;

		return Character.toLowerCase(str.charAt(str.length() - 1)) == Character.toLowerCase(end);
	}

	public static final boolean endsWithIgnoreCase(String str, String end) {
		if ((str == null) || (end == null))
			return false;

		if (end.length() > str.length())
			return false;

		String temp = str.substring(str.length() - end.length(), str.length());

		return temp.equalsIgnoreCase(end);
	}

	public static final String delete(String str, char ch) {
		if (str == null || str.isEmpty())
			return str;

		StringBuilder buffer = new StringBuilder(str.length());
		int count = 0;
		int start = 0;
		int pos = 0;
		int len = str.length();

		while ((pos = str.indexOf(ch, start)) >= 0) {
			count++;
			buffer.append(str, start, pos);
			start = pos + 1;
		}

		if (count > 0) {
			if (start < len)
				buffer.append(str, start, len);
			return buffer.toString();
		} else
			return str;
	}

	public static final String delete(String str, String substr) {
		if (str == null || str.isEmpty() || substr == null || substr.isEmpty())
			return str;

		StringBuilder buffer = new StringBuilder(str.length());
		int count = 0;
		int start = 0;
		int pos = 0;
		int len = str.length();
		int sublen = substr.length();

		while ((pos = str.indexOf(substr, start)) >= 0) {
			count++;
			buffer.append(str, start, pos);
			start = pos + sublen;
		}

		if (count > 0) {
			if (start < len)
				buffer.append(str, start, len);
			return buffer.toString();
		} else
			return str;
	}

	public static final String replace(String str, char oldSub, char newSub) {
		if (str == null || str.isEmpty())
			return str;

		StringBuilder buffer = new StringBuilder(str.length());
		int count = 0;
		int start = 0;
		int pos = 0;
		int len = str.length();

		while ((pos = str.indexOf(oldSub, start)) >= 0) {
			count++;
			buffer.append(str, start, pos).append(newSub);
			start = pos + 1;
		}

		if (count > 0) {
			if (start < len)
				buffer.append(str, start, len);
			return buffer.toString();
		} else
			return str;
	}

	public static final String replace(String str, String oldSub, String newSub) {
		if (str == null || str.isEmpty() || oldSub == null || oldSub.isEmpty())
			return str;

		StringBuilder buffer = new StringBuilder(str.length());
		int count = 0;
		int start = 0;
		int pos = 0;
		int len = str.length();
		int sublen = oldSub.length();

		while ((pos = str.indexOf(oldSub, start)) >= 0) {
			count++;
			buffer.append(str, start, pos);
			if (newSub != null)
				buffer.append(newSub);
			start = pos + sublen;
		}

		if (count > 0) {
			if (start < len)
				buffer.append(str, start, len);
			return buffer.toString();
		} else
			return str;
	}

	public static final String reverse(String str) {
		if (str == null || str.isEmpty())
			return str;

		int length = str.length();
		char[] reverse = new char[length];

		for (int i = 0; i < length; i++)
			reverse[i] = str.charAt(length - i - 1);

		return new String(reverse);
	}

	public static final String repeat(String s, int count) {
		StringBuilder buf = new StringBuilder(count * s.length());
		for (int i = 0; i < count; i++)
			buf.append(s);
		return buf.toString();
	}

	public static final String shorten(String str, int length) {
		if (str == null || str.isEmpty())
			return null;

		if (str.length() > length)
			return str.substring(0, length);
		else
			return str;
	}

	public static final String[] split(String str, String delim) {
		if (str == null || str.isEmpty())
			return new String[0];

		if (delim == null || delim.isEmpty())
			return new String[] { str };

		List<String> fields = new ArrayList<>();

		int pos = 0;
		int start = 0;
		int len = str.length();
		int delimlen = delim.length();
		int count = 0;

		while ((pos = str.indexOf(delim, start)) >= 0) {
			count++;
			fields.add(str.substring(start, pos));
			start = pos + delimlen;
		}

		if (count > 0) {
			if (len > start)
				fields.add(str.substring(start));
			return (String[]) fields.toArray(new String[0]);
		} else
			return new String[] { str };
	}

	public static final String[] split(String str, String delim, int num) {
		if (str == null || str.isEmpty() || num == 0)
			return new String[0];

		if (delim == null || delim.isEmpty())
			return new String[] { str };

		String[] fields = new String[num];
		int offset = 0;
		int pos = 0;
		int idx = 0;
		int len = delim.length();

		while (true) {
			pos = str.indexOf(delim, offset);
			if (pos < 0) {
				if (offset < str.length())
					fields[idx++] = str.substring(offset);
				break;
			}

			fields[idx++] = str.substring(offset, pos);
			offset = pos + len;
			if (idx == num - 1) {
				if (str.endsWith(delim))
					fields[idx] = str.substring(offset, str.length() - len);
				else
					fields[idx] = str.substring(offset);
				break;
			}
			pos = str.indexOf(delim, offset);
		}
		return fields;
	}

	public static final String[] split(String str, char ch, int num) {
		if (str == null || str.isEmpty() || num == 0)
			return new String[0];

		String[] fields = new String[num];
		int offset = 0;
		int pos = 0;
		int idx = 0;
		int len = 1;

		while (true) {
			pos = str.indexOf(ch, offset);
			if (pos < 0) {
				if (offset < str.length())
					fields[idx++] = str.substring(offset);
				break;
			}

			fields[idx++] = str.substring(offset, pos);
			offset = pos + len;
			if (idx == num - 1) {
				if (str.charAt(str.length() - 1) == ch)
					fields[idx] = str.substring(offset, str.length() - 1);
				else
					fields[idx] = str.substring(offset);
				break;
			}
			pos = str.indexOf(ch, offset);
		}

		return fields;
	}

	public static final String before(String src, String delim) {
		return before(src, delim, 0);
	}

	public static final String before(String src, String delim, int no) {
		if (src == null || delim == null || src.isEmpty() || delim.isEmpty())
			return null;
		if (no < 0)
			no = 0;

		int count = 0;
		int start = 0;
		int pos = 0;
		int length = delim.length();

		while ((pos = src.indexOf(delim, start)) >= 0) {
			if (count++ == no)
				break;
			start = pos + length;
		}

		if (pos > 0)
			return src.substring(0, pos);
		else if (pos == 0)
			return null;
		else
			return src;
	}

	public static final String after(String src, String delim) {
		return after(src, delim, 0);
	}

	public static final String after(String src, String delim, int no) {
		if (src == null || delim == null || src.isEmpty() || delim.isEmpty())
			return null;

		if (no < 0)
			no = 0;

		int count = 0;
		int start = 0;
		int pos = 0;
		int length = delim.length();

		while ((pos = src.indexOf(delim, start)) >= 0) {
			if (count++ == no)
				break;
			start = pos + length;
		}

		if (pos >= 0)
			return src.substring(pos + length);
		else
			return null;
	}

	public static final String trim(String str) {
		if (str == null || str.isEmpty())
			return str;

		int start = str.length();
		for (int i = 0; i < str.length(); i++) {
			if (!Character.isWhitespace(str.charAt(i))) {
				start = i;
				break;
			}
		}

		int end = 0;
		for (int i = str.length() - 1; i > start; i--) {
			if (!Character.isWhitespace(str.charAt(i))) {
				end = i;
				break;
			}
		}

		if (start <= end)
			return str.substring(start, end + 1);
		else
			return BLANK;
	}

	public static final String trimLeading(String str) {
		if (str == null || str.isEmpty())
			return str;

		for (int i = 0; i < str.length(); i++) {
			if (!Character.isWhitespace(str.charAt(i)))
				return str.substring(i, str.length());
		}

		return BLANK;
	}

	public static final String trimTrailing(String str) {
		if (str == null || str.isEmpty())
			return str;

		for (int i = str.length() - 1; i >= 0; i--) {
			if (!Character.isWhitespace(str.charAt(i)))
				return str.substring(0, i + 1);
		}

		return BLANK;
	}

	public static final String trim(String str, char ch) {
		if (str == null || str.isEmpty())
			return str;

		int start = str.length();
		for (int i = 0; i < str.length(); i++) {
			if (ch != str.charAt(i)) {
				start = i;
				break;
			}
		}

		int end = 0;
		for (int i = str.length() - 1; i > start; i--) {
			if (ch != str.charAt(i)) {
				end = i;
				break;
			}
		}

		if (start <= end)
			return str.substring(start, end + 1);
		else
			return BLANK;
	}

	public static final String trimLeading(String str, char ch) {
		if (str == null || str.isEmpty())
			return str;

		for (int i = 0; i < str.length(); i++) {
			if (ch != str.charAt(i))
				return str.substring(i, str.length());
		}

		return BLANK;
	}

	public static final String trimTrailing(String str, char ch) {
		if (str == null || str.isEmpty())
			return str;

		for (int i = str.length() - 1; i >= 0; i--) {
			if (ch != str.charAt(i))
				return str.substring(0, i + 1);
		}

		return BLANK;
	}

	public static final String recruit(String src, int total, char ch) {
		return recruit(src, total, ch, false);
	}

	public static final String recruit(String src, int total, char ch, boolean tail) {
		if (src == null || src.isEmpty()) {
			int len = total;
			if (len <= 0)
				return src;

			char[] arr = new char[len];
			Arrays.fill(arr, ch);

			return new String(arr);
		} else {
			int len = total - src.length();
			if (len <= 0)
				return src;

			char[] arr = new char[len];
			Arrays.fill(arr, ch);

			if (tail)
				return src + new String(arr);
			else
				return new String(arr) + src;
		}
	}

	public static final byte[] getBytes(String src, String encoding) {
		try {
			return src == null ? null : encoding == null ? src.getBytes() : src.getBytes(encoding);
		} catch (UnsupportedEncodingException err) {
			throw new IllegalArgumentException(err);
		}
	}

	public static final void append(StringBuilder buf, String str, int offset, int length) {
		int end = offset + length;
		for (int i = offset; i < end; ++i) {
			if (i >= str.length())
				break;
			buf.append(str.charAt(i));
		}
	}

	public static final void append(StringBuilder buf, byte b, int base) {
		int bi = 0xFF & b;
		int c = 48 + bi / base % base;
		if (c > 57)
			c = 39 + c;// 97 + c - 48 - 10
		buf.append((char) c);
		c = 48 + bi % base;
		if (c > 57)
			c = 39 + c;// 97 + c - 48 - 10
		buf.append((char) c);
	}

	public static final String concat(String origin, String tailor) {
		return origin + tailor;
	}

	public static final String insert(String orgin, String header) {
		return header + orgin;
	}

}